// ./middleware/verifyToken.js: 权限认证接口(包含登陆验证和角色验证)
const jwt = require("jsonwebtoken");
const { promisify } = require("util");
const { UserManager } = require("../mongodb/manager");
const config = require("../config.js");
const secretKey = config.jwtSecret; // 确保这个密钥与生成 token 时相同

// 验证 token 的中间件
const verifyToken = (requiredRole = "user") => {
  return async (ctx, next) => {
    const token = ctx.cookies.get("token");

    // 检查登陆状态
    if (!token) {
      ctx.status = 401; // 未授权
      ctx.body = { message: "Please log in" };
      return;
    }

    // 检查角色权限
    try {
      // TODO: 权限验证有一个小问题, 不应该存储所有的用户信息, 因为这样后端更新前端很难频繁更新, 应该直接存储 id 值, 这样重新取出得到后端的响应就是新的值了!
      // 验证 token
      const decoded = await promisify(jwt.verify)(token, secretKey);
      const user = await UserManager.getUserById(decoded.id); // 将用户信息存入 ctx.state
      ctx.state.user = user; // 将用户信息存入上下文中

      // 权限验证逻辑
      if (requiredRole === "admin" && user.role !== "admin") {
        ctx.status = 403; // 禁止访问
        ctx.body = { message: "Access denied. Admins only." };
        return;
      }

      // TODO: 如果角色是 merchant，可以自定义逻辑，例如:
      // if (requiredRole === 'merchant' && user.role !== 'merchant') {
      //   ctx.status = 403; // 禁止访问
      //   ctx.body = { message: "Access denied. Merchants only." };
      //   return;
      // }

      await next(); // 调用下一个中间件或路由处理函数
    } catch (error) {
      console.error("Token verification error:", error);
      ctx.status = 401; // 未授权
      ctx.body = { message: "Invalid token" };
    }
  };
};

module.exports = verifyToken;
